(function( $, undefined ) {

$.widget("ui.ajajform_foreign_key",$.ui.ajajform_widget, {
	options: {
		// \type cssclass
		cssclass: "afw-foreign-key",
		value: {},
		values: [],
		available: [],
		multiselect: false,
		inline: false,
		label: "",
		html: false,
		width: null,
		form: undefined,
		not_null: false,
		form_result_name: "name",
		widgets: [],
		dialog: {},
		empty: "",
		htmltemplate_single: '<div class="af-label"></div><div class="af-value"><div class="af-item"></div><div class="af-error"></div></div><div class="af-button af-button-edit"></div><div style="clear: both;"></div>',
		htmltemplate_multiselect: '<div class="af-label"></div><div class="af-value"><div class="af-items"></div><div class="af-buttons-add"><div class="af-button af-button-add"></div><div style="clear: both;"></div><div class="af-error"></div></div></div><div style="clear: both;"></div>',
		readonly: false
	},
	i18n: {
		ru: {create_button:"Создать",edit_button:"Сохранить",err_empty:"Поле должно быть заполнено"},
		en: {create_button:"Create",edit_button:"Save",err_empty:"Field must be filled"}
	},
	/**
	 * Creates everything, called on construction
	 */
	_create: function() {
		this.element.addClass(this.options.cssclass);
		this.element.append(this.options.multiselect?this.options.htmltemplate_multiselect:this.options.htmltemplate_single);
		this.refreshLabel();
		this.refreshWidth();
		var t=this;	
		$(".af-button",this.element).bind("click",function() {t.newEditClicked();});
		this.refreshValue();
		this.refreshReadonly();
	},
	/**
	 *
	 */
	refreshReadonly: function() {
		if (this.options.readonly) this.element.addClass("afw-foreign-key-read-only"); else  this.element.removeClass("afw-foreign-key-read-only");
	},
	/**
	 *
	 */
	newEditClicked: function() {
		if (this.options.readonly) return;
		var name=(this.options.inline)?"inlineOpen":"popupOpen";
		var val;
		if (!this.options.multiselect) val=this.options.value;
		this[name](val);
	},
	/**
	 * Renders html part for available choices
	 *
	 * @return {jQuery} html block
	 */
	renderAvailable: function(val) {
		var t=this;
		var ex=t.options.available;
		if (!ex) return {html:"",found:false};
		if (!ex.length) return {html:"",found:false};
		var found=false;
		var r="<div class='scroller'><table class='af-available' border='0'>\n<tr><th></th></tr>\n";
		for (var j=0;j<ex.length;j++) {
//			console.log([val,ex[j]]);
			var fnow=val && val.id==ex[j].id;
			if (fnow) found=true;
			r+="<tr><td"+(fnow?" class='active'":"")+"><div>"+this.genName(ex[j])+"</div></td></tr>";
		}
		r+="</table></div>\n";
		r=$(r);
		for (var j=0;j<ex.length;j++) {
			$("tr:eq("+(j+1)+") td:eq(0)",r).bind("click",{id:ex[j].id,value:ex[j]},function(e) {
				t.selected(e.data.value);
			});
		}
		return {html:r,found:found};
	},
	/**
	 * 
	 */
	editClicked: function(i) {
		if (this.options.readonly) return;
		var v;
		if (this.options.multiselect) v=this.options.values[i]; else v=this.options.value;
		if (this.options.inline) this.inlineOpen(v,i); else this.popupOpen(v,i);
	},
	/**
	 * Creates and opens a popup dialog to choose existing or enter new
	 */
	popupOpen: function(val,i) {
		var t=this;
		var lefthtml=this.renderAvailable(val);
		if (!this.options.form) {	
			var dialogoptions={
				width: t.options.dialog.width,
				height: t.options.dialog.height
			};
			html_dialog(dialogoptions,lefthtml.html);
			t.dialogid=dialogoptions.id;
			return;
		}
		var params={};
		if (val) params.i=i;
		var dialogoptions={
				width: t.options.dialog.width,
				height: t.options.dialog.height,
				submit: {
					value: (t.options.form.submit&&t.options.form.submit.value)?t.options.form.submit.value:this.gettext(val?"edit_button":"create_button"),
					params: params,
					click: function(r,r2) {
						t.popupNewSelected(r,r2);
					}
				},
				title: t.options.dialog.title,
				lefthtml: lefthtml.html
			};
		var widgets=this.genFormWidgets(lefthtml.found?undefined:val);
		ajajform_dialog(dialogoptions,t.options.form,widgets);
		t.dialogid=dialogoptions.id;
	},
	/**
	 *
	 */
	genFormWidgets: function(val) {
		var widgets=JSON.parse(JSON.stringify(this.options.widgets));
		if (!val) return widgets;
		for (var i=0;i<widgets.length;i++) {
			var wname=widgets[i].name;
			if (!(wname in val)) continue;
			switch (widgets[i].type) {
				case "textedit":
					widgets[i].value=val[wname];
					break;
				default:
					console.log("ajajform_foreign_key::popupOpen(): Unknown type "+widgets[i].type);
			}
		}
		return widgets;
	},
	/**
	 */
	popupNewSelected: function(r,r2) {
		this.selected(r);
	},
	/**
	 * Called on selection of available or on submit when entering new
	 *
	 * @param {integer} id - id or null. id if entry exists
	 * @param {string} name - name to display
	 * @param {Object} object - object or null. Object if non-exisistent entry added, null if existent
	 */
	selected: function(object) {
//		if (object) id=object;
		if (!this.options.multiselect) {
			this.options.value=object;
		} else {
			console.log(object);
			if ("i" in object) {
				this.options.values.splice(object.i,1,object);
			} else {
				this.options.values.push(object);
			}
		}
		this.refreshValue();
		$("#"+this.dialogid).remove();
	},
	/**
	 * Called on removal
	 */
	deselected: function(pos) {
		if (this.options.multiselect) {
			this.options.values.splice(pos,1);
		} else {
			this.options.value={};
		}
		this.refreshValue();
	},
	/**
	 *
	 */
	refreshWidth: function() {
		if (this.options.multiselect) {
			$(".af-value",this.element).width(this.options.width);
			$(".af-value2",this.element).width(this.options.width);
		} else {
			$(".af-value",this.element).width(this.options.width-19);
			$(".af-value2",this.element).width(this.options.width-19);
		}
	},
	/**
	 *
	 */
	refreshLabel: function() {
		$(".af-label",this.element).text(this.options.label);
	},
	/**
	 *
	 */
	genName: function(val) {
		if (!this.options.form_result_name) return val.name;
		var f=this.options.form_result_name;
		if (typeof f == "function") return f(val);
		return val[f];
	},
	/**
	 *
	 */
	refreshValue: function() {
		var t=this;
		if (this.options.multiselect) {
			var div=$(".af-value .af-items",this.element);
			var v=this.options.values;
			div.empty();
			for (var i=0;i<v.length;i++) {
				var div2=$("<div class='af-item'><div class='af-content'></div><div class='af-button-edit'></div><div class='af-button-delete'></div><div class='cl'></div></div>").appendTo(div);
				$(".af-content",div2)[this.options.html?"html":"text"](this.genName(v[i])).width(this.options.width-19*2);
				$(".af-button-delete",div2).bind("click",{i:i},function(e) {t.deselected(e.data.i)});
				$(".af-button-edit",div2).bind("click",{i:i},function(e) {t.editClicked(e.data.i)});
			}
			if (v.length==0) div.text(this.options.empty);
		} else {
			var div=$(".af-value .af-item",this.element);
			var v=this.options.value;
			if (typeof v=="number") {
				for (var i=0;i<this.options.available.length;i++) if (v==this.options.available[i].id) {v=this.options.value=this.options.available[i];break;}
			}
			div[this.options.html?"html":"text"](this.genName(v));
//			if (!v) div.text(this.options.empty);
		}
	},
	postvalue: function(r) {
		if (this.options.multiselect) {
			r[this.options.name]=JSON.stringify(this.options.values);
		} else {
			r[this.options.name]=JSON.stringify(this.options.value);
		}
	},
	validate: function() {
		var vd=this.options.validate;
		var r;
		if (vd) r=vd(this.options.multiselect?this.options.values:this.options.value);
		if (!r) {
			if (this.options.not_null) {
				if (this.options.multiselect) {
					if (!this.options.values ||this.options.values.length==0) r=this.gettext("err_empty");
				} else {
					var i;
					if (this.options.value) for (var k in this.options.value) i=1;
					if (!i) r=this.gettext("err_empty");
				}
			}
		}
		this.refreshError(r);
		return r?true:false;
	}
});

})( jQuery );

